四种单例模式实际都是有运用的。
懒汉式单例模式:
优点:延迟加载
缺点:不加同步的懒汉式是线程不安全的,加了synchronized之后就变成线程安全的了
public class Singleton {
private static Singleton singleton = null;
private Singleton(){
}
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
优点:线程安全
缺点:浪费内存空间
实例应用:java.lang.Runtime
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return singleton ;
}
}
特点:性能又保证线程安全
注意:其实双重检查模式就是对懒汉模式的优化,在new Singleton之前,加一个类锁。注意,成员变量singleton最好使用volatile修饰,否则若在无参构造中初始化一个其他的成员变量,会产生指令重排序,导致新创建的对象获取不到最新的成员变量值。
public class Singleton{
private static volatile Singleton singleton;
private Singleton(){
}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
Holder单例模式(工作中常用):
特点:既实现懒加载,性能好,线程安全
声明类时,成员变量中不声明实例变量,而是放到静态内部类中。这种方式和懒汉式有些相似,它们都采用了类装载的机制来保证初始化实例时只有一个线程,不同的是,Holder单例模式是将实例的初始化放到了静态类中去实现,从而实现了懒加载。
因为private static HolderSingleton instance = new HolderSingleton();只会被加载一次
public class HolderSingleton {
// 外部类的私有构造方法
private HolderSingleton() {
}
// 外部类静态方法,通过静态内部类的静态成员变量获取
public static HolderSingleton getInstance() {
return Holder.instance;
}
// 静态内部类内部加载的时候创建外部类,只加载一次,所以只创建一个
private static class Holder {
private static HolderSingleton instance = new HolderSingleton();
}
}